package org.dromara.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.compress.archivers.zip.UnicodePathExtraField;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.FileUtils;
import org.dromara.common.core.utils.ServletUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.excel.core.ExcelResult;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.system.domain.*;
import org.dromara.system.domain.bo.SysSocialBo;
import org.dromara.system.domain.bo.WbCompanyInfoBo;
import org.dromara.system.domain.vo.*;
import org.dromara.system.listener.SysUserImportListener;
import org.dromara.system.mapper.*;
import org.dromara.system.service.DianWangService;
import org.dromara.system.service.ISysOssService;
import org.dromara.system.service.IWbCompanyInfoService;
import org.dromara.system.utils.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.core.io.Resource;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.io.*;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;


/**
 * 电网数据 服务层实现
 *
 * @author Feng c
 */
@RequiredArgsConstructor
@Service
public class DianWangServiceImpl implements DianWangService {

    private static final int BUFFER_SIZE = 64578; // 设置缓冲区大小

    private final WbItemInfoMapper wbItemInfoMapper;

    private final WbGoodsListInfoMapper wbGoodsListInfoMapper;

    private final WbMinuteBidBagMapper wbMinuteBidBagMapper;

    private final WbMinuteFileMapper wbMinuteFileMapper;

    private final WbMinuteListMapper wbMinuteListMapper;

    private final WbDemandListMapper wbDemandListMapper;

    private final WbItemFileMapper wbItemFileMapper;

    private final WbCompanyInfoMapper wbCompanyInfoMapper;

    private final WbCompanyCertMapper wbCompanyCertMapper;

    private final WbProductAchievementMapper wbProductAchievementMapper;

    private final WbProductEquipmentMapper wbProductEquipmentMapper;

    private final WbTestEquipmentMapper wbTestEquipmentMapper;

    private final WbOperatingProductsListMapper wbOperatingProductsListMapper;

    private final IWbCompanyInfoService wbCompanyInfoService;



    private final ISysOssService ossService;

    private final WbCandidateInfoMapper wbCandidateInfoMapper;
    private final WbCandidateFileMapper wbCandidateFileMapper;
    private final WbCandidateListMapper wbCandidateListMapper;

    private static WebClient webClient;
    private final WbItemInfoServiceImpl wbItemInfoServiceImpl;

    private String contentType ="application/json";

    private static final int TEN = 10;
    private static final int HUNDRED = 100;
    private static final int ONE_ZERO_TWO_FOUR = 1024;

    static {
        webClient = WebClient.builder().baseUrl("https://ecp.sgcc.com.cn").codecs(obj -> obj.defaultCodecs().maxInMemorySize(HUNDRED * ONE_ZERO_TWO_FOUR * ONE_ZERO_TWO_FOUR)).build();
    }

    /**
     * 获取采购公告列表数据
     * @param param_json
     * @return
     */
    private JSONObject noteList(JSONObject param_json) {
        String response = webClient.post().uri("/ecp2.0/ecpwcmcore//index/noteList")
            .header("Content-Type",contentType).bodyValue(param_json).retrieve().bodyToMono(String.class)
            .block(); // 使用block()阻塞并等待结果
        return new JSONObject(response);
    }

    /**
     * 根据ID获取采购公告详情
     * @param id
     * @return
     */
    private JSONObject getNoticeBid(String id) {
        String response = webClient.post().uri("/ecp2.0/ecpwcmcore//index/getNoticeBid")
            .header("Content-Type",contentType).bodyValue(id).retrieve().bodyToMono(String.class)
            .block(); // 使用block()阻塞并等待结果
        return new JSONObject(response);
    }

    /**
     * 根据ID获取中标结果详情 / 推荐中标候选人详情
     * @param id
     * @return
     */
    private JSONObject getNoticeWin(String id) {
        String response = webClient.post().uri("/ecp2.0/ecpwcmcore//index/getNoticeWin")
            .header("Content-Type",contentType).bodyValue(id).retrieve().bodyToMono(String.class)
            .block(); // 使用block()阻塞并等待结果
        return new JSONObject(response);
    }
    /**
     * 获取中标文件数据
     * @param id
     * @return
     */
    private JSONObject getWinFile(String id) {
        String response = webClient.post().uri("/ecp2.0/ecpwcmcore//index/getWinFile")
            .header("Content-Type",contentType).bodyValue(id).retrieve().bodyToMono(String.class)
            .block(); // 使用block()阻塞并等待结果
        return new JSONObject(response);
    }

    private JSONObject getFile(String id) {
        String response = webClient.post().uri("/ecp2.0/ecpwcmcore//index/getFile")
            .header("Content-Type",contentType).bodyValue(id).retrieve().bodyToMono(String.class)
            .block(); // 使用block()阻塞并等待结果
        return new JSONObject(response);
    }

    /**
     * 根据ID获取变更公告详情
     * @param id
     * @return
     */
    private JSONObject getChangeBid(String id) {
        String response = webClient.post().uri("/ecp2.0/ecpwcmcore//index/getChangeBid")
            .header("Content-Type",contentType).bodyValue(id).retrieve().bodyToMono(String.class)
            .block(); // 使用block()阻塞并等待结果
        return new JSONObject(response);
    }

    /**
     * 根据ID获取废标公告详情
     * @param id
     * @return
     */
    private JSONObject getDoc(String id) {
        String response = webClient.post().uri("/ecp2.0/ecpwcmcore//index/getDoc")
            .header("Content-Type",contentType).bodyValue(id).retrieve().bodyToMono(String.class)
            .block(); // 使用block()阻塞并等待结果
        return new JSONObject(response);
    }

    /**
     * 下载采购公告附件
     * @param id
     * @return
     */
    private void downLoadBid(String id) {
        try {
            // 记录下开始下载时的时间
            Instant now = Instant.now();
            //发送请求
            ClientResponse response = webClient.get().uri("/ecp2.0/ecpwcmcore//index/downLoadBid?noticeId="+id+"&noticeDetId=null")  // 请求路径
                .accept(MediaType.APPLICATION_OCTET_STREAM).exchange().block(); // 获取响应体
            String fileName = "";
            // 从header中获取原始文件名
            if (response != null) {
                HttpHeaders httpHeaders = response.headers().asHttpHeaders();
                String content = httpHeaders.getFirst(HttpHeaders.CONTENT_DISPOSITION);
                if (content != null) {
                    fileName = ServletUtils.urlDecode(content).replaceAll("attachment; filename=","");
                }
                String prefix = fileName.substring(0, fileName.lastIndexOf("."));
                String suffix = fileName.substring(fileName.lastIndexOf("."));
                File tempFile = File.createTempFile(prefix, suffix);
                Resource resource = response.bodyToMono(Resource.class).block();
                if (resource != null) {
                    FileUtils.copyInputStreamToFile(resource.getInputStream(), tempFile);
                }
                this.saveFile(tempFile,id,fileName);//保存附件信息
                this.unzip(tempFile,id);//解压文件
                tempFile.delete();//删除临时文件
            }
            System.out.println("文件下载完成，耗时：" + ChronoUnit.SECONDS.between(now, Instant.now()) + " 秒");
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private boolean isValidBigDecimal(String str) {
        try {
            new BigDecimal(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 下载中标结果PDF附件
     * @param path
     */
    private String downLoadBidPDF(String path,String id,String fileName,String type) {
        String item_no = "";
        try {
            // 记录下开始下载时的时间
            Instant now = Instant.now();
            //发送请求
            ClientResponse response = webClient.get().uri("/ecp2.0/ecpwcmcore//index/showPDF?filePath="+path)  // 请求路径
                .accept(MediaType.APPLICATION_OCTET_STREAM).exchange().block(); // 获取响应体
            // 从header中获取原始文件名
            if (response != null) {
                HttpHeaders httpHeaders = response.headers().asHttpHeaders();
                String content = httpHeaders.getFirst(HttpHeaders.CONTENT_DISPOSITION);
                if (content != null) {
                    fileName = ServletUtils.urlDecode(content).replaceAll("attachment; filename=","");
                }
                String prefix = fileName.substring(0, fileName.lastIndexOf("."));
                String suffix = fileName.substring(fileName.lastIndexOf("."));
                File tempFile = File.createTempFile(prefix, suffix);
                Resource resource = response.bodyToMono(Resource.class).block();
                if (resource != null) {
                    FileUtils.copyInputStreamToFile(resource.getInputStream(), tempFile);
                }
                this.saveFilePDF(tempFile,id,fileName,type);//保存附件信息
                List<Map> list_map = PdfToMapConverter.handlePdfTable(new FileInputStream(tempFile));
                if("01".equals(type)){//处理中标pdf数据
                    List<WbMinuteList> list_obj = analyzeMap(list_map,"wbMinuteBidBagId",Long.parseLong(id),WbMinuteList.class,"WbMinuteList");
                    int index = 1;
                    for (int i = 0; i < list_obj.size(); i++) {
                        WbMinuteList wbMinuteList = list_obj.get(i);
                        if(StringUtils.isNotEmpty(wbMinuteList.getSubStandardId()) || StringUtils.isNotEmpty(wbMinuteList.getSubStandardName())){
                            wbMinuteList.setSort(index++);//排序
                            if(StringUtils.isNotEmpty(wbMinuteList.getCompanyName())){
                                wbCompanyInfoService.handleName(wbMinuteList.getCompanyName());
                            }
                            if(StringUtils.isNotEmpty(wbMinuteList.getPriceDescription()) && isValidBigDecimal(wbMinuteList.getPriceDescription())){
                                wbMinuteList.setPrice(wbMinuteList.getPriceDescription());
                            }else if(StringUtils.isNotEmpty(wbMinuteList.getSubStandardId()) || StringUtils.isNotEmpty(wbMinuteList.getSubStandardName())){
                                List<WbCandidateListVo> list = wbCandidateListMapper.selectVoList(new LambdaQueryWrapper<WbCandidateList>()
                                    .eq(StringUtils.isNotEmpty(wbMinuteList.getSubStandardId()), WbCandidateList::getSubStandardId,wbMinuteList.getSubStandardId())
                                    .eq(StringUtils.isNotEmpty(wbMinuteList.getSubStandardName()), WbCandidateList::getSubStandardName,wbMinuteList.getSubStandardName())
                                    .eq(StringUtils.isNotEmpty(wbMinuteList.getBagNo()), WbCandidateList::getBagNo,wbMinuteList.getBagNo())
                                    .eq(StringUtils.isNotEmpty(wbMinuteList.getBagName()), WbCandidateList::getBagName,wbMinuteList.getBagName()));
                                if(list.size() == 1){
                                    wbMinuteList.setPrice(list.get(0).getPriceOrDiscount());
                                }
                            }
                            wbMinuteListMapper.insert(wbMinuteList);
                        }
                    }
                }else if("02".equals(type)){//处理候选人pdf数据
                    List<WbCandidateList> list_obj = analyzeMap(list_map,"candidateId",Long.parseLong(id),WbCandidateList.class,"WbCandidateList");
                    int index = 1;
                    for (int i = 0; i < list_obj.size(); i++) {
                        WbCandidateList wbCandidateList = list_obj.get(i);
                        if(StringUtils.isNotEmpty(wbCandidateList.getSubStandardId()) || StringUtils.isNotEmpty(wbCandidateList.getSubStandardName())){
                            wbCandidateList.setSort((index++)+"");//排序
                            if(StringUtils.isNotEmpty(wbCandidateList.getCandidate())){
                                wbCompanyInfoService.handleName(wbCandidateList.getCandidate());
                            }
                            if(StringUtils.isNotEmpty(wbCandidateList.getPriceDescription()) && isValidBigDecimal(wbCandidateList.getPriceDescription())){
                                wbCandidateList.setPriceOrDiscount(wbCandidateList.getPriceDescription());
                            }else if(StringUtils.isNotEmpty(wbCandidateList.getSubStandardId()) || StringUtils.isNotEmpty(wbCandidateList.getSubStandardName())){
                                List<WbCandidateListVo> list = wbCandidateListMapper.selectVoList(new LambdaQueryWrapper<WbCandidateList>()
                                    .eq(StringUtils.isNotEmpty(wbCandidateList.getSubStandardId()), WbCandidateList::getSubStandardId,wbCandidateList.getSubStandardId())
                                    .eq(StringUtils.isNotEmpty(wbCandidateList.getSubStandardName()), WbCandidateList::getSubStandardName,wbCandidateList.getSubStandardName())
                                    .eq(StringUtils.isNotEmpty(wbCandidateList.getBagNo()), WbCandidateList::getBagNo,wbCandidateList.getBagNo())
                                    .eq(StringUtils.isNotEmpty(wbCandidateList.getBagName()), WbCandidateList::getBagName,wbCandidateList.getBagName()));
                                if(list.size() == 1){
                                    wbCandidateList.setPriceOrDiscount(list.get(0).getPriceOrDiscount());
                                }
                            }
                            wbCandidateListMapper.insert(wbCandidateList);
                        }
                    }
                }
//                wbMinuteListMapper.insertBatch(list_obj);
                //-----------------------获取项目编号----------------------//
                String pdf_context = PdfToMapConverter.extractTextFromPDF(tempFile);
                item_no = DianWangUtil.handItemNo(item_no,pdf_context);
                tempFile.delete();//删除临时文件
            }
            System.out.println("文件下载完成，耗时：" + ChronoUnit.SECONDS.between(now, Instant.now()) + " 秒");
        }catch (Exception e){
            e.printStackTrace();
        }
        return item_no;
    }

    private void saveWbCandidateFilePDF(File file, String id, String originalName) {
        SysOssVo sysOssVo = ossService.upload(file);
        WbCandidateFile wbMinuteFile = new WbCandidateFile();
        wbMinuteFile.setOssId(sysOssVo.getOssId());
        wbMinuteFile.setCandidateId(Long.valueOf(id));
        if(StringUtils.isNotEmpty(originalName)){
            wbMinuteFile.setFileOriginalName(originalName);
        }else{
            wbMinuteFile.setFileOriginalName(sysOssVo.getOriginalName());
        }
        wbMinuteFile.setFileName(sysOssVo.getFileName());
        wbMinuteFile.setUrl(sysOssVo.getUrl());
        wbCandidateFileMapper.insert(wbMinuteFile);//保存附件信息
    }

    /**
     * 解压文件类型判断
     * @param file
     */
    private void unzip(File file,String id) throws Exception {
        String fileName = file.getName();
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        if(".zip".equals(suffix)){
            File destDirectory = new File("/files/");
            this.unzip(file,destDirectory,id);//开始解压
        }else if(suffix.equals(ExcelTypeEnum.XLSX.getValue())){
            if(id == null){//公司.zip解压内容分析
                List<Map> result_ = ExcelUtil.importExcel(new FileInputStream(file),"基本信息");
                WbCompanyInfo wbCompanyInfo = new WbCompanyInfo();
                for (int i = 0; i < result_.size(); i++) {
                    Map map = result_.get(i);
                    Set set = map.keySet();
                    int f1 = 0;//记录null数据项
                    for (Object key : set){
                        Object value = map.get(key);
                        if(value == null){
                            f1 = f1 + 1;
                        }else{
                            CompanyInfoFieldEnum companyInfoFieldEnum = CompanyInfoFieldEnum.findByFieldName(map.get(key).toString());
                            if(companyInfoFieldEnum != null){
                                ObjectUtil.setFieldValue(wbCompanyInfo,companyInfoFieldEnum.getField(),map.get(Integer.parseInt(key.toString())+1));
                            }
                        }
                        if(f1 == 5) break;
                    }
                }
                if(StringUtils.isNotEmpty(wbCompanyInfo.getName())){
                    List<WbCompanyInfoVo> list = wbCompanyInfoMapper.selectVoList(new LambdaQueryWrapper<WbCompanyInfo>().eq(WbCompanyInfo::getName,wbCompanyInfo.getName()));
                    if(list.size() > 0){
                        wbCompanyInfo.setId(list.get(0).getId());
                        wbCompanyInfo.setStatus(list.get(0).getStatus());
                        wbCompanyInfoMapper.updateById(wbCompanyInfo);
                    } else {
                        wbCompanyInfo.setStatus("0");
                        wbCompanyInfoMapper.insert(wbCompanyInfo);
                    }
                    //------------------------设置公司经营产品----------------------------------------//
                    String regex = "_([^_]+)核实结果";
                    Pattern pattern = Pattern.compile(regex);
                    Matcher matcher = pattern.matcher(fileName);
                    WbOperatingProductsList wbOperatingProductsList = new WbOperatingProductsList();
                    if (matcher.find()) {
                        String captured = matcher.group(1); // 捕获组1是我们想要的部分
//                        captured = captured.replaceAll("核实结果模板（省公司）","");
//                        captured = captured.replaceAll("核实结果模板（总部委托省公司）","");
//                        captured = captured.replaceAll("核实结果模板","");
                        wbOperatingProductsList.setCompanyId(wbCompanyInfo.getId());
                        wbOperatingProductsList.setProductName(captured);
                        List<WbOperatingProductsListVo> list_WbOperatingProductsList = wbOperatingProductsListMapper.selectVoList(new LambdaQueryWrapper<WbOperatingProductsList>()
                            .eq(WbOperatingProductsList::getCompanyId,wbOperatingProductsList.getCompanyId())
                            .eq(WbOperatingProductsList::getProductName,wbOperatingProductsList.getProductName()));
                        if(list_WbOperatingProductsList.size() == 0){
                            wbOperatingProductsListMapper.insert(wbOperatingProductsList);
                        }
//                        System.out.println(captured); // 输出: 10kV变压器核实结果模板（省公司）
                    }
                    //------------------------设置为无效数据----------------------------------------//
                    wbCompanyCertMapper.update(new LambdaUpdateWrapper<WbCompanyCert>().set(WbCompanyCert::getDataTagging,"0").eq(WbCompanyCert::getCompanyId,wbCompanyInfo.getId()));
                    wbProductAchievementMapper.update(new LambdaUpdateWrapper<WbProductAchievement>().set(WbProductAchievement::getDataTagging,"0").eq(WbProductAchievement::getCompanyId,wbCompanyInfo.getId()));
                    wbProductEquipmentMapper.update(new LambdaUpdateWrapper<WbProductEquipment>().set(WbProductEquipment::getDataTagging,"0").eq(WbProductEquipment::getCompanyId,wbCompanyInfo.getId()));
                    wbTestEquipmentMapper.update(new LambdaUpdateWrapper<WbTestEquipment>().set(WbTestEquipment::getDataTagging,"0").eq(WbTestEquipment::getCompanyId,wbCompanyInfo.getId()));
                    //------------------------报告证书----------------------------------------//
                    List<Map> result1 = ExcelUtil.importExcel(new FileInputStream(file),"报告证书");
                    Map<Object, CompanyCertFieldEnum> map_companyCertFieldEnum = new HashMap<>();
                    for (int i = 0; i < result1.size(); i++) {
                        Map map = result1.get(i);
                        Set set = map.keySet();
                        if(map_companyCertFieldEnum.keySet().size() == 0){
                            int f1 = 0;//记录null数据项
                            int f2 = 0;//记录行数
                            for (Object key : set){
                                Object value = map.get(key);
                                if(value == null){
                                    f1 = f1 + 1;
                                }else{
                                    CompanyCertFieldEnum companyCertFieldEnum = CompanyCertFieldEnum.findByFieldName(map.get(key).toString());
                                    if(companyCertFieldEnum != null){
                                        map_companyCertFieldEnum.put(key,companyCertFieldEnum);
                                        if(f2==0 && result1.get(i+1) != null && result1.get(i+1).get(key) == null){
                                            f2 = 2; i++;
                                        }else if(f2 == 0 ){
                                            f2 = 1;
                                        }
                                    }else if(f2 == 2){
                                        companyCertFieldEnum = CompanyCertFieldEnum.findByFieldName(result1.get(i+1).get(key).toString());
                                        if(companyCertFieldEnum != null){
                                            map_companyCertFieldEnum.put(key,companyCertFieldEnum);
                                        }
                                    }
                                }
                                if(f1 == 5) break;
                            }
                        }else{
                            int count = map_companyCertFieldEnum.keySet().size();
                            WbCompanyCert wbCompanyCert = new WbCompanyCert();
                            for (Object key : map_companyCertFieldEnum.keySet()){
                                if(cn.hutool.core.util.ObjectUtil.isNotNull(map.get(key))){
                                    count--;
                                    ObjectUtil.setFieldValue(wbCompanyCert,map_companyCertFieldEnum.get(key).getField(),map.get(key));
                                }
                            }
                            if(map_companyCertFieldEnum.keySet().size()/2 >= count){
                                wbCompanyCert.setCompanyId(wbCompanyInfo.getId());
                                wbCompanyCert.setCompanyName(wbCompanyInfo.getName());
                                wbCompanyCertMapper.insert(wbCompanyCert);//保存数据
                            }else{
                                map_companyCertFieldEnum = new HashMap<>();//重置数据
                            }
                        }
                    }
                    //------------------------产品业绩----------------------------------------//
                    List<Map> result2 = ExcelUtil.importExcel(new FileInputStream(file),"产品业绩");
                    Map<Object, ProductAchievementFieldEnum> map_ProductAchievementFieldEnum = new HashMap<>();
                    for (int i = 0; i < result2.size(); i++) {
                        Map map = result2.get(i);
                        Set set = map.keySet();
                        if(map_ProductAchievementFieldEnum.keySet().size() == 0){
                            int f1 = 0;//记录null数据项
                            int f2 = 0;//记录行数
                            for (Object key : set){
                                Object value = map.get(key);
                                if(value == null){
                                    f1 = f1 + 1;
                                }else{
                                    ProductAchievementFieldEnum productAchievementFieldEnum = ProductAchievementFieldEnum.findByFieldName(map.get(key).toString());
                                    if(productAchievementFieldEnum != null){
                                        map_ProductAchievementFieldEnum.put(key,productAchievementFieldEnum);
                                        if(f2==0 && result2.get(i+1) != null && result2.get(i+1).get(key) == null){
                                            f2 = 2; i++;
                                        }else if(f2 == 0 ){
                                            f2 = 1;
                                        }
                                    }else if(f2 == 2){
                                        productAchievementFieldEnum = ProductAchievementFieldEnum.findByFieldName(result2.get(i+1).get(key).toString());
                                        if(productAchievementFieldEnum != null){
                                            map_ProductAchievementFieldEnum.put(key,productAchievementFieldEnum);
                                        }
                                    }
                                }
                                if(f1 == 5) break;
                            }
                        }else{
                            int count = map_ProductAchievementFieldEnum.keySet().size();
                            WbProductAchievement wbProductAchievement = new WbProductAchievement();
                            for (Object key : map_ProductAchievementFieldEnum.keySet()){
                                if(cn.hutool.core.util.ObjectUtil.isNotNull(map.get(key))){
                                    count--;
                                    ObjectUtil.setFieldValue(wbProductAchievement,map_ProductAchievementFieldEnum.get(key).getField(),map.get(key));
                                }
                            }
                            if(map_ProductAchievementFieldEnum.keySet().size()/2 >= count){
                                wbProductAchievement.setCompanyId(wbCompanyInfo.getId());
                                wbProductAchievement.setCompanyName(wbCompanyInfo.getName());
                                if(StringUtils.isNotEmpty(wbOperatingProductsList.getProductName())){
                                    wbProductAchievement.setOperatingProductsName(wbOperatingProductsList.getProductName());
                                }
                                wbProductAchievementMapper.insert(wbProductAchievement);//保存数据
                            }else{
                                map_ProductAchievementFieldEnum = new HashMap<>();//重置数据
                            }
                        }
                    }
                    //------------------------生产制造----------------------------------------//
                    List<Map> result3 = ExcelUtil.importExcel(new FileInputStream(file),"生产制造");
                    Map<Object, ProductEquipmentFieldEnum> map_ProductEquipmentFieldEnum = new HashMap<>();
                    for (int i = 0; i < result3.size(); i++) {
                        Map map = result3.get(i);
                        Set set = map.keySet();
                        if(map_ProductEquipmentFieldEnum.keySet().size() == 0){
                            int f1 = 0;//记录null数据项
                            int f2 = 0;//记录行数
                            for (Object key : set){
                                Object value = map.get(key);
                                if(value == null){
                                    f1 = f1 + 1;
                                }else{
                                    ProductEquipmentFieldEnum productEquipmentFieldEnum = ProductEquipmentFieldEnum.findByFieldName(map.get(key).toString());
                                    if(productEquipmentFieldEnum != null){
                                        map_ProductEquipmentFieldEnum.put(key,productEquipmentFieldEnum);
                                        if(f2==0 && result3.get(i+1) != null && result3.get(i+1).get(key) == null){
                                            f2 = 2; i++;
                                        }else if(f2 == 0 ){
                                            f2 = 1;
                                        }
                                    }else if(f2 == 2){
                                        productEquipmentFieldEnum = ProductEquipmentFieldEnum.findByFieldName(result3.get(i+1).get(key).toString());
                                        if(productEquipmentFieldEnum != null){
                                            map_ProductEquipmentFieldEnum.put(key,productEquipmentFieldEnum);
                                        }
                                    }
                                }
                                if(f1 == 5) break;
                            }
                        }else{
                            int count = map_ProductEquipmentFieldEnum.keySet().size();
                            WbProductEquipment wbProductEquipment = new WbProductEquipment();
                            for (Object key : map_ProductEquipmentFieldEnum.keySet()){
                                if(cn.hutool.core.util.ObjectUtil.isNotNull(map.get(key))){
                                    count--;
                                    ObjectUtil.setFieldValue(wbProductEquipment,map_ProductEquipmentFieldEnum.get(key).getField(),map.get(key));
                                }
                            }
                            if(map_ProductEquipmentFieldEnum.keySet().size()/2 >= count){
                                wbProductEquipment.setCompanyId(wbCompanyInfo.getId());
                                wbProductEquipment.setCompanyName(wbCompanyInfo.getName());
                                wbProductEquipmentMapper.insert(wbProductEquipment);//保存数据
                            }else{
                                map_ProductEquipmentFieldEnum = new HashMap<>();//重置数据
                            }
                        }
                    }
                    //------------------------试验检测----------------------------------------//
                    List<Map> result4 = ExcelUtil.importExcel(new FileInputStream(file),"试验检测");
                    Map<Object, TestEquipmentFieldEnum> map_TestEquipmentFieldEnum = new HashMap<>();
                    for (int i = 0; i < result4.size(); i++) {
                        Map map = result4.get(i);
                        Set set = map.keySet();
                        if(map_TestEquipmentFieldEnum.keySet().size() == 0){
                            int f1 = 0;//记录null数据项
                            int f2 = 0;//记录行数
                            for (Object key : set){
                                Object value = map.get(key);
                                if(value == null){
                                    f1 = f1 + 1;
                                }else{
                                    TestEquipmentFieldEnum testEquipmentFieldEnum = TestEquipmentFieldEnum.findByFieldName(map.get(key).toString());
                                    if(testEquipmentFieldEnum != null){
                                        map_TestEquipmentFieldEnum.put(key,testEquipmentFieldEnum);
                                        if(f2==0 && result4.get(i+1) != null && result4.get(i+1).get(key) == null){
                                            f2 = 2; i++;
                                        }else if(f2 == 0 ){
                                            f2 = 1;
                                        }
                                    }else if(f2 == 2){
                                        testEquipmentFieldEnum = TestEquipmentFieldEnum.findByFieldName(result4.get(i+1).get(key).toString());
                                        if(testEquipmentFieldEnum != null){
                                            map_TestEquipmentFieldEnum.put(key,testEquipmentFieldEnum);
                                        }
                                    }
                                }
                                if(f1 == 5) break;
                            }
                        }else{
                            int count = map_TestEquipmentFieldEnum.keySet().size();
                            WbTestEquipment wbTestEquipment = new WbTestEquipment();
                            for (Object key : map_TestEquipmentFieldEnum.keySet()){
                                if(cn.hutool.core.util.ObjectUtil.isNotNull(map.get(key))){
                                    count--;
                                    ObjectUtil.setFieldValue(wbTestEquipment,map_TestEquipmentFieldEnum.get(key).getField(),map.get(key));
                                }
                            }
                            if(map_TestEquipmentFieldEnum.keySet().size()/2 >= count){
                                wbTestEquipment.setCompanyId(wbCompanyInfo.getId());
                                wbTestEquipment.setCompanyName(wbCompanyInfo.getName());
                                wbTestEquipmentMapper.insert(wbTestEquipment);//保存数据
                            }else{
                                map_TestEquipmentFieldEnum = new HashMap<>();//重置数据
                            }
                        }
                    }
                }
            }else{
                int sheetNo = 0;
                wbGoodsListInfoMapper.delete(new LambdaQueryWrapper<WbGoodsListInfo>().eq(WbGoodsListInfo::getItemId, id));
                while (sheetNo >= 0){
                    FileInputStream in = new FileInputStream(file);
                    if(fileName.indexOf("货物清单") >= 0){
                        ExcelResult<WbGoodsListInfoVo> result = ExcelUtil.importExcel(in,sheetNo++, WbGoodsListInfoVo.class,true);
                        for (WbGoodsListInfoVo wbGoodsListInfoVo : result.getList()){
                            WbGoodsListInfo wbGoodsListInfo = BeanUtil.toBean(wbGoodsListInfoVo, WbGoodsListInfo.class);
                            wbGoodsListInfo.setItemId(id);
                            wbGoodsListInfoMapper.insert(wbGoodsListInfo);
                        }
                        if(result.getList().size() == 0) sheetNo = -1;
                    }else{
                        List<Map> result = ExcelUtil.importExcel(in,sheetNo++);
                        Map<Object,ItemBagFieldEnum> map_itemBagFieldEnum = new HashMap<>();
                        for (int i = 0; i < result.size(); i++) {
                            Map map = result.get(i);
                            Set set = map.keySet();
                            if(map_itemBagFieldEnum.keySet().size() == 0){
                                int f1 = 0;//记录null数据项
                                int f2 = 0;//记录行数
                                for (Object key : set){
                                    Object value = map.get(key);
                                    if(value == null){
                                        f1 = f1 + 1;
                                    }else{
                                        ItemBagFieldEnum itemBagFieldEnum = ItemBagFieldEnum.findByFieldName(map.get(key).toString());
                                        if(itemBagFieldEnum != null){
                                            map_itemBagFieldEnum.put(key,itemBagFieldEnum);
                                            if(f2==0 && result.get(i+1) != null && result.get(i+1).get(key) == null){
                                                f2 = 2; i++;
                                            }else if(f2 == 0 ){
                                                f2 = 1;
                                            }
                                        }else if(f2 == 2){
                                            itemBagFieldEnum = ItemBagFieldEnum.findByFieldName(result.get(i+1).get(key).toString());
                                            if(itemBagFieldEnum != null){
                                                map_itemBagFieldEnum.put(key,itemBagFieldEnum);
                                            }
                                        }
                                    }
                                    if(f1 == 5) break;
                                }
                            }else{
                                int count = map_itemBagFieldEnum.keySet().size();
                                WbDemandList wbDemandList = new WbDemandList();
                                for (Object key : map_itemBagFieldEnum.keySet()){
                                    if(cn.hutool.core.util.ObjectUtil.isNotNull(map.get(key))){
                                        count--;
                                        ObjectUtil.setFieldValue(wbDemandList,map_itemBagFieldEnum.get(key).getField(),map.get(key));
                                    }
                                }
                                if(map_itemBagFieldEnum.keySet().size()/2 >= count){
                                    wbDemandList.setItemId(id);
                                    wbDemandListMapper.insert(wbDemandList);//保存数据
                                }else{
                                    map_itemBagFieldEnum = new HashMap<>();//重置数据
                                }
                            }
                        }
                        if(result.size() == 0) sheetNo = -1;
                    }
                }
                this.saveFile(file,id,null);//保存附件信息
                file.delete();
            }
        }else{
            this.saveFile(file,id,null);//保存附件信息
            file.delete();
        }
    }

    /**
     * 公共处理List<MAP>方法
     * @param result
     * @param parentFieldName 父字段名称（外键）
     * @param parentFieldValue 父字段值
     * @param clazz 转换对象
     * @param tableName 表名
     * @return
     */
    private <T>List<T> analyzeMap(List<Map> result,String parentFieldName,Object parentFieldValue,Class<T> clazz,String tableName){
        List<T> list = new ArrayList<>();
        try {
            if("2024062046689471".equals(parentFieldValue.toString().trim())){
                System.out.println("test");
            }
            int home_index = -1;
            int index = 0;
            Map<Object,CommonFieldEnum> map_commonFieldEnum = new HashMap<>();
            boolean is_sort = false;//是否存在序号
            for (int i = 0; i < result.size(); i++) {
                Map map = result.get(i);
                Set set = map.keySet();
                if(map_commonFieldEnum.keySet().size() == 0){
                    StringBuilder title_s_01 = new StringBuilder();
                    int f1 = 0;//记录null数据项
                    for (Object key : set){
                        Object value = map.get(key);
                        if(value == null){
                            f1 = f1 + 1;
                        }else{
                            title_s_01.append(value);//添加字段名称
                            CommonFieldEnum commonFieldEnum = CommonFieldEnum.findByFieldName(map.get(key).toString(),tableName);
                            if(commonFieldEnum != null){
                                map_commonFieldEnum.put(key,commonFieldEnum);
                                index = i;
                                if(home_index == -1){
                                    home_index = i;
                                }
                            }
                        }
                        if(f1 == 5) break;
                    }
                    if(map_commonFieldEnum.keySet().size() > 0 && result.size() > i){//检查合并标题
                        int next_title = 1;
                        while (next_title > 0){
                            boolean next_title_is_value = true;
                            for (Object key : map_commonFieldEnum.keySet()){
                                if("".equals(result.get(i+next_title).get(key).toString())){
                                    next_title_is_value = false;
                                    break;
                                }
                            }
                            if(!next_title_is_value){//判定无值
                                for (Object key : result.get(i+next_title).keySet()){
                                    CommonFieldEnum commonFieldEnum = CommonFieldEnum.findByFieldName(result.get(i+next_title).get(key).toString(),tableName);
                                    if(commonFieldEnum != null){
                                        map_commonFieldEnum.put(key,commonFieldEnum);
                                    }
                                }
                                i++;
                                if(result.size() > i){
                                    next_title++;
                                }
                            }else{
                                next_title = -1;//停止
                            }
                        }
                    }
                    if(list.size() > 0 && map_commonFieldEnum.keySet().size() > 0){
                        boolean is_xt = true;//标题是否相同
                        for (Object key : set){
                            if(!map.get(key).equals(result.get(home_index).get(key))){
                                is_xt = false;
                            }
                        }
                        if(!is_xt && (title_s_01.toString().indexOf("服务费") >= 0 || title_s_01.toString().indexOf("代理费") >= 0)){//判定为排除的标题
                            map_commonFieldEnum = new HashMap<>();//重置数据
                        }
                    }
                    if(map_commonFieldEnum.keySet().size() > 0 && map.get(0)!=null && "序号".equals(map.get(0).toString().trim())){
                        is_sort = true;//存在序号
                    }
                }else{
                    int count = map_commonFieldEnum.keySet().size();
                    boolean check_bo = true;
                    if(map.keySet().size() == 1 && "FC_ZT_666".equals(map.get(0))){
                        check_bo = false;
                        if(result.size()-1 > i){//下方有数据
                            boolean is_title = false;
                            if(result.get(i+1).size() != result.get(i-1).size()){
                                map_commonFieldEnum = new HashMap<>();//重置数据
                            }else{
                                for (Object key : map_commonFieldEnum.keySet()){
                                    CommonFieldEnum commonFieldEnum = CommonFieldEnum.findByFieldName(result.get(i+1).get(key).toString(),tableName);
                                    if(commonFieldEnum != null){
                                        is_title = true;
                                    }
                                }
                                if(is_title){
                                    map_commonFieldEnum = new HashMap<>();//重置数据
                                } else {
                                    StringBuilder title_s_01 = new StringBuilder();
                                    StringBuilder title_s_02 = new StringBuilder();

                                    for (Object key : map_commonFieldEnum.keySet()){
                                        title_s_01.append(map_commonFieldEnum.get(key).getFieldName());
                                        if(cn.hutool.core.util.ObjectUtil.isNotNull(result.get(i+1).get(key))){
                                            title_s_02.append(result.get(i+1).get(key));
                                        }
                                    }
                                    if(title_s_01.toString().equals(title_s_02.toString())){//存在标题（跳过标题）
                                        i++;
                                    }else{
                                        if(is_sort && StringUtils.isEmpty(result.get(i+1).get(0).toString()) && list.size() > 0){//存在序号直接合并
                                            T c = list.get(list.size()-1);
                                            for (Object key : map_commonFieldEnum.keySet()){
                                                if(cn.hutool.core.util.ObjectUtil.isNotNull(result.get(i+1).get(key))){
                                                    Field field = clazz.getDeclaredField(map_commonFieldEnum.get(key).getField());
                                                    Object field_value = GenericUtil.getFieldValue(c, field);
                                                    GenericUtil.setFieldValue(c, field, field_value + result.get(i+1).get(key).toString().replaceAll(" ","")); // 使用泛型安全的setFieldValue
                                                }
                                            }
                                            i++;
                                        }else{
                                            StringBuilder title_s_03 = new StringBuilder();
                                            for (Object key : result.get(i+1).keySet()){
                                                if(result.get(i+1).get(key) != null){
                                                    title_s_03.append(result.get(i+1).get(key));
                                                }
                                            }
                                            if(title_s_03.toString().indexOf("服务费") >= 0 || title_s_03.toString().indexOf("代理费") >= 0){//存在排除的标题
                                                map_commonFieldEnum = new HashMap<>();//重置数据
                                                i++;
                                            }else{
                                                boolean check_data = false;
                                                for (Object key : map_commonFieldEnum.keySet()){//只对比第一个数字
                                                    if(result.size() > 2 && result.get(i-2).get(key).toString().length() - result.get(i+1).get(key).toString().length()>1){
                                                        check_data = true;
                                                    }
                                                    break;
                                                }
                                                if(check_data){//合并数据
                                                    T c = list.get(list.size()-1);
                                                    for (Object key : map_commonFieldEnum.keySet()){
                                                        if(cn.hutool.core.util.ObjectUtil.isNotNull(result.get(i+1).get(key))){
                                                            Field field = clazz.getDeclaredField(map_commonFieldEnum.get(key).getField());
                                                            Object field_value = GenericUtil.getFieldValue(c, field);
                                                            GenericUtil.setFieldValue(c, field, field_value + result.get(i+1).get(key).toString().replaceAll(" ","")); // 使用泛型安全的setFieldValue
                                                        }
                                                    }
                                                    i++;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if(check_bo){
                        if(i > 0 && (("FC_ZT_666".equals(result.get(i-1).get(0)) && map.size() != result.get(i-2).size())
                            || (!"FC_ZT_666".equals(result.get(i-1).get(0)) && map.size() != result.get(i-1).size()))){
                            map_commonFieldEnum = new HashMap<>();//表格列数不同重置数据
                            i--;
                        }
                        T oj = clazz.getDeclaredConstructor().newInstance();
                        for (Object key : map_commonFieldEnum.keySet()){
                            if(cn.hutool.core.util.ObjectUtil.isNotNull(map.get(key))){
                                count--;
//                            ObjectUtil.setFieldValue(oj,map_commonFieldEnum.get(key).getField(),map.get(key));
                                Field field = clazz.getDeclaredField(map_commonFieldEnum.get(key).getField());
                                if(map.get(key) != null && StringUtils.isNotEmpty(map.get(key).toString())){
                                    GenericUtil.setFieldValue(oj, field, map.get(key).toString().replaceAll(" ","")); // 使用泛型安全的setFieldValue
                                }else{
                                    for (int j = i-1; j > index; j--) {
                                        if(result.get(j).get(key) != null && StringUtils.isNotEmpty(result.get(j).get(key).toString())){
                                            GenericUtil.setFieldValue(oj, field, result.get(j).get(key).toString().replaceAll(" ",""));
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        if(map_commonFieldEnum.keySet().size()/2 >= count){
//                        ObjectUtil.setFieldValue(oj,parentFieldName,parentFieldValue);
                            Field parentField = clazz.getDeclaredField(parentFieldName);
                            GenericUtil.setFieldValue(oj, parentField, parentFieldValue);
                            list.add(oj);
                        }else{
                            map_commonFieldEnum = new HashMap<>();//重置数据
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }


        return list;
    }
    public class GenericUtil {
        public static <T> void setFieldValue(T target, Field field, Object value) throws IllegalAccessException {
            field.setAccessible(true);
            // 类型检查，确保值可以安全地转换为目标字段类型
            if (!field.getType().isAssignableFrom(value.getClass())) {
                throw new IllegalArgumentException("Cannot assign value of type " + value.getClass() + " to field of type " + field.getType());
            }
            field.set(target, value);
        }
        public static <T> Object getFieldValue(T target, Field field) throws IllegalAccessException {
            field.setAccessible(true);
            return field.get(target);
        }
    }
    /**
     * 保存附件信息（招标项目）
     * @param file
     * @param id
     */
    private void saveFile(File file,String id,String originalName){
        SysOssVo sysOssVo = ossService.upload(file);
        WbItemFile wbItemFile = new WbItemFile();
        wbItemFile.setOssId(sysOssVo.getOssId());
        wbItemFile.setItemId(Long.valueOf(id));
        if(StringUtils.isNotEmpty(originalName)){
            wbItemFile.setFileOriginalName(originalName);
        }else{
            wbItemFile.setFileOriginalName(sysOssVo.getOriginalName());
        }
        wbItemFile.setFileName(sysOssVo.getFileName());
        wbItemFile.setUrl(sysOssVo.getUrl());
        wbItemFileMapper.insert(wbItemFile);//保存附件信息
    }

    /**
     * 保存附件信息（中标项目）
     * @param file
     * @param id
     * @param originalName
     */
    private void saveFilePDF(File file,String id,String originalName,String type){
        SysOssVo sysOssVo = ossService.upload(file);
        if("01".equals(type)){//中标附件
            WbMinuteFile wbMinuteFile = new WbMinuteFile();
            wbMinuteFile.setOssId(sysOssVo.getOssId());
            wbMinuteFile.setWbMinuteBidBagId(Long.valueOf(id));
            if(StringUtils.isNotEmpty(originalName)){
                wbMinuteFile.setFileOriginalName(originalName);
            }else{
                wbMinuteFile.setFileOriginalName(sysOssVo.getOriginalName());
            }
            wbMinuteFile.setFileName(sysOssVo.getFileName());
            wbMinuteFile.setUrl(sysOssVo.getUrl());
            wbMinuteFileMapper.insert(wbMinuteFile);//保存附件信息
        }else if("02".equals(type)){//推荐人附件
            WbCandidateFile wbCandidateFile = new WbCandidateFile();
            wbCandidateFile.setOssId(sysOssVo.getOssId());
            wbCandidateFile.setCandidateId(Long.valueOf(id));
            if(StringUtils.isNotEmpty(originalName)){
                wbCandidateFile.setFileOriginalName(originalName);
            }else{
                wbCandidateFile.setFileOriginalName(sysOssVo.getOriginalName());
            }
            wbCandidateFile.setFileName(sysOssVo.getFileName());
            wbCandidateFile.setUrl(sysOssVo.getUrl());
            wbCandidateFileMapper.insert(wbCandidateFile);//保存附件信息
        }
    }


    /**
     * 解压文件
     * @param zipFile
     * @param destDirectory
     * @throws IOException
     */
    public void unzip(File zipFile, File destDirectory,String id) throws IOException {
        try (ZipFile zip = new ZipFile(zipFile,"GBK")) {
            zip.getEntries().asIterator().forEachRemaining(entry -> {
                File destFile = new File(destDirectory, entry.getName());
                if (entry.isDirectory()) {
                    destFile.mkdirs();
                } else {
                    destFile.getParentFile().mkdirs();
                    try (InputStream in = zip.getInputStream(entry)) {
                        FileUtils.copyInputStreamToFile(in, destFile);
                        this.unzip(destFile,id);//文件类型判断
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
    }

    @Override
    public void handleTendering() {
        int index  = 0;
        Long count = 0L;
        while (true){
            Long total =  wbItemInfoMapper.selectCount(new LambdaQueryWrapper<WbItemInfo>().eq(WbItemInfo::getDataSourceMenu,"ECP_ZB"));
            total = total + 7879-44;
            JSONObject json_result = this.noteList(new JSONObject("{firstPageMenuId:\"2018032700291334\",noticeType:\"100063001\",index:"+(++index)+",size:2}"));
            if(json_result.getBool("successful")){//成功
                List<WbItemInfo> list_wbItemInfo = new ArrayList<>();
                count = json_result.getJSONObject("resultValue").getLong("count");
                JSONArray noteList = json_result.getJSONObject("resultValue").getJSONArray("noteList");
                int sizt = noteList.size();
                if(count - total < 2){
                    sizt = Integer.parseInt(count.toString()) - Integer.parseInt(total.toString());
                }
                for (int i = 0; i < sizt; i++) {
                    JSONObject note = noteList.getJSONObject(i);
                    if("doci-change".equals(note.getStr("doctype"))){//变更公告
                        JSONObject json_notice = this.getChangeBid(note.getStr("id")).getJSONObject("resultValue").getJSONObject("chgNotice");
                        insertOrSaveWbItemInfo(note,json_notice,list_wbItemInfo,"ECP","ECP_ZB","doci-change");
                    }else if("doci-bid".equals(note.getStr("doctype"))){//采购公告
                        JSONObject json_notice = this.getNoticeBid(note.getStr("id")).getJSONObject("resultValue").getJSONObject("notice");
                        insertOrSaveWbItemInfo(note,json_notice,list_wbItemInfo,"ECP","ECP_ZB","doc-spec");
                    }else if("doc-spec".equals(note.getStr("doctype"))){//招标公告
                        JSONObject json_notice = this.getDoc(note.getStr("id")).getJSONObject("resultValue").getJSONObject("doc");
                        insertOrSaveWbItemInfo(note,json_notice,list_wbItemInfo,"ECP","ECP_ZB","doc-spec");
                    }else{
                        System.out.println("未记录的公告类型："+note.getStr("doctype"));
                    }
                    checkBag(note.getLong("id"));//根据id检查分标分包信息
                }
                wbItemInfoMapper.insertOrUpdateBatch(list_wbItemInfo);
            }
            if(count - total <= 2) break;
        }
    }

    @Override
    public void handlePurchase() {
        int index  = 0;
        Long count = 0L;
        while (true){
            Long total =  wbItemInfoMapper.selectCount(new LambdaQueryWrapper<WbItemInfo>().eq(WbItemInfo::getDataSourceMenu,"ECP_CG"));
            total = total + 26038;
            JSONObject json_result = this.noteList(new JSONObject("{firstPageMenuId:\"2018032900295987\",index:"+(++index)+",size:2}"));
            if(json_result.getBool("successful")){//成功
                List<WbItemInfo> list_wbItemInfo = new ArrayList<>();
                count = json_result.getJSONObject("resultValue").getLong("count");
                JSONArray noteList = json_result.getJSONObject("resultValue").getJSONArray("noteList");
                int sizt = noteList.size();
                if(count - total < 2){
                    sizt = Integer.parseInt(count.toString()) - Integer.parseInt(total.toString());
                }
                for (int i = 0; i < sizt; i++) {
                    JSONObject note = noteList.getJSONObject(i);
                    if("doci-change".equals(note.getStr("doctype"))){//变更公告
                        JSONObject json_notice = this.getChangeBid(note.getStr("id")).getJSONObject("resultValue").getJSONObject("chgNotice");
                        insertOrSaveWbItemInfo(note,json_notice,list_wbItemInfo,"ECP","ECP_CG","doci-change");
                    }else if("doci-bid".equals(note.getStr("doctype"))){//采购公告
                        JSONObject json_notice = this.getNoticeBid(note.getStr("id")).getJSONObject("resultValue").getJSONObject("notice");
                        insertOrSaveWbItemInfo(note,json_notice,list_wbItemInfo,"ECP","ECP_CG","doci-bid");
                    }else if("doc-spec".equals(note.getStr("doctype"))){//招标公告
                        JSONObject json_notice = this.getDoc(note.getStr("id")).getJSONObject("resultValue").getJSONObject("doc");
                        insertOrSaveWbItemInfo(note,json_notice,list_wbItemInfo,"ECP","ECP_CG","doci-bid");
                    }else{
                        System.out.println("未记录的公告类型："+note.getStr("doctype"));
                    }
                    checkBag(note.getLong("id"));//根据id检查分标分包信息
                }
                wbItemInfoMapper.insertOrUpdateBatch(list_wbItemInfo);
            }
            if(count - total <= 2) break;
        }
    }

    @Override
    public void saveFile(MultipartFile file, String itemId) {
        File file1 = null;
        try {
            file1 = this.convertMultipartFileToFile(file);
            this.saveFile(file1,itemId,null);
            this.unzip(file1,itemId);//解压文件
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
//        checkBag(Long.parseLong(itemId));//根据id检查分标分包信息
    }

    @Override
    public void unzipCompanyInfo(MultipartFile file) {
        try {
            File file1 = convertMultipartFileToFile(file);
            unzip(file1,null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void handleWinningTheBid() {
        int index  = 0;
        Long count = 0L;
        while (true){
            Long total =  wbMinuteBidBagMapper.selectCount(new LambdaQueryWrapper<WbMinuteBidBag>().eq(WbMinuteBidBag::getDataSource, "ECP"));
            total = total + 31394-153;
            JSONObject json_result = this.noteList(new JSONObject("{firstPageMenuId:\"2018060501171111\",index:"+(++index)+",size:2}"));
            if(json_result.getBool("successful")){//成功
                List<WbMinuteBidBag> list_WbMinuteBidBag = new ArrayList<>();
                count = json_result.getJSONObject("resultValue").getLong("count");
                JSONArray noteList = json_result.getJSONObject("resultValue").getJSONArray("noteList");
                int sizt = noteList.size();
                if(count - total < 2){
                    sizt = Integer.parseInt(count.toString()) - Integer.parseInt(total.toString());
                }
                for (int i = 0; i < sizt; i++) {
                    JSONObject note = noteList.getJSONObject(i);
                    if("doci-win".equals(note.getStr("doctype").trim())){//中标结果
                        JSONObject jSONObject = this.getNoticeWin(note.getStr("id")).getJSONObject("resultValue");
                        insertOrSaveWbMinuteBidBag(note,jSONObject.getJSONObject("notice"),list_WbMinuteBidBag,jSONObject.getStr("fileFlag"));
                    }else if("doc-com".equals(note.getStr("doctype").trim())){//成交公告
                        JSONObject json_notice = this.getDoc(note.getStr("id")).getJSONObject("resultValue").getJSONObject("doc");
                        insertOrSaveWbMinuteBidBag(note,json_notice,list_WbMinuteBidBag,json_notice.getStr("fileFlag"));
                    }else{
                        System.out.println("未记录的公告类型："+note.getStr("doctype"));
                    }
                }
                wbMinuteBidBagMapper.insertOrUpdateBatch(list_WbMinuteBidBag);
            }
            if(count - total <= 2) break;
        }
    }

    /**
     * html解析表格
     * @param html
     * @return
     */
    @Override
    public List<Map> handleHtmlTable(String html) {
        Document doc = Jsoup.parseBodyFragment(html);
        // 选择表格元素
        Element table = doc.select("table").first();
        // 获取表格的行
        Elements rows = table.select("tr");
        // 遍历每一行
        List<Map> list  = new ArrayList<>();
        for (Element row : rows) {
            Map<Object,Object> map = new HashMap<>();
            Elements cols = row.select("td"); // 获取该行的列
            // 提取并打印每列的数据
            for(int i =0 ;i<cols.size();i++){
                map.put(i, cols.get(i).text());
            }
            list.add(map);
        }
        return list;
    }

    /**
     * 处理推荐中标候选人公示
     */
    @Override
    public void handleCandidateInfo() throws ParseException {
        int index  = 0;
        Long count = 0L;
        while (true){
            Long total =  wbCandidateInfoMapper.selectCount(new LambdaQueryWrapper<WbCandidateInfo>().eq(WbCandidateInfo::getDataSource, "ECP"));
            total = total + 19293-163;
            JSONObject json_result = this.noteList(new JSONObject("{firstPageMenuId:\"2018060501171107\",index:"+(++index)+",size:2}"));
            if(json_result.getBool("successful")){//成功
                List<WbCandidateInfo> list_wbCandidateInfo = new ArrayList<>();
                count = json_result.getJSONObject("resultValue").getLong("count");
                JSONArray noteList = json_result.getJSONObject("resultValue").getJSONArray("noteList");
                int size = noteList.size();
                if(count - total < 2){
                    size = Integer.parseInt(count.toString()) - Integer.parseInt(total.toString());
                }
                for (int i = 0; i < size; i++) {
                    JSONObject note = noteList.getJSONObject(i);
                    if(note!=null){
                        if("doci-win".equals(note.getStr("doctype"))){//中标结果
                            JSONObject json_notice = this.getNoticeWin(note.getStr("id")).getJSONObject("resultValue").getJSONObject("notice");
                            String fileFlag = this.getNoticeWin(note.getStr("id")).getJSONObject("resultValue").getStr("fileFlag");
                            insertOrSaveWbCandidateInfo(note,json_notice,list_wbCandidateInfo,fileFlag);
                        }else{
                            System.out.println("未记录的公告类型："+note.getStr("doctype"));
                        }
                    }
                }
                wbCandidateInfoMapper.insertOrUpdateBatch(list_wbCandidateInfo);
            }
            if(count - total <= 2) break;
        }
    }


    private void insertOrSaveWbCandidateInfo(JSONObject note, JSONObject jsonNotice, List<WbCandidateInfo> listWbCandidateInfo, String fileFlag) throws ParseException {
        if(wbCandidateInfoMapper.selectVoById(note.getLong("id")) == null){
            WbCandidateInfo wbCandidateInfo = new WbCandidateInfo();
            wbCandidateInfo.setId(note.getLong("id"));
            wbCandidateInfo.setHeadline(note.getStr("title"));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            wbCandidateInfo.setPublicityTime(sdf.parse(note.getStr("noticePublishTime")));
            if(StringUtils.isNotEmpty(note.getStr("noticePublishTime"))){
                wbCandidateInfo.setYear(note.getStr("noticePublishTime").substring(0,4));
            }
            String content = jsonNotice.getStr("CONT");
            wbCandidateInfo.setContent(content);
            wbCandidateInfo.setTenderee(jsonNotice.getStr("bidOrgName"));
            wbCandidateInfo.setTenderAgent(jsonNotice.getStr("bidagtName"));
            if("1".equals(fileFlag)){//有文件
                //下载前清空附件信息
                wbCandidateFileMapper.delete(new LambdaQueryWrapper<WbCandidateFile>().eq(WbCandidateFile::getCandidateId, wbCandidateInfo.getId()));
                JSONObject json_file = this.getWinFile(note.getStr("id"));
                JSONArray jsonArray_file = json_file.getJSONObject("resultValue").getJSONArray("files");
                for (int i = 0; i < jsonArray_file.size(); i++) {
                    JSONObject file = jsonArray_file.getJSONObject(i);
                    String item_no = this.downLoadBidPDF(file.getStr("FILE_PATH"),note.getStr("id"),file.getStr("FILE_NAME"),"02");//开始下载文件
                    if(item_no != null && item_no.length() > 200) {
                        item_no = item_no.substring(0,200);
                    }
                    item_no = DianWangUtil.handHtmlItemNo(item_no,wbCandidateInfo.getContent());
                    if(StringUtils.isNotEmpty(item_no) && item_no.length() > 2){
                        wbCandidateInfo.setPurchaseNo(item_no);
                    }
                }
            }else{
                // 无文件、解析html
                wbCandidateListMapper.delete(new LambdaQueryWrapper<WbCandidateList>().eq(WbCandidateList::getCandidateId, wbCandidateInfo.getId()));
                // 采购编号
//                String purchaseNo = handleHtmlPurchaseNo(content,6);
//                wbCandidateInfo.setPurchaseNo(purchaseNo);
                // 读取获取list<map>列表
                List<Map> list = HtmlToMapConverter.handleHtmlTable(content);
                List <WbCandidateList> resultList = analyzeMap(list,"candidateId",wbCandidateInfo.getId(),WbCandidateList.class,"WbCandidateList");
                for (int i = 0; i < resultList.size(); i++) {
                    wbCompanyInfoService.handleName(resultList.get(i).getCandidate());
                }
                wbCandidateListMapper.insertBatch(resultList);
                //-----------------------获取项目编号----------------------//
                if(StringUtils.isNotEmpty(wbCandidateInfo.getContent())){
                    Document doc = Jsoup.parse(wbCandidateInfo.getContent());
                    // 获取纯文本内容
                    String textOnly = doc.text().replaceAll(" ","");
                    String itemNo = DianWangUtil.handHtmlItemNo("",textOnly);
                    if(StringUtils.isNotEmpty(itemNo) && itemNo.length() > 2){
                        wbCandidateInfo.setPurchaseNo(itemNo);
                    }
                }
            }
            wbCandidateInfo.setDataSource("ECP");//数据来源：ECP平台
            Long wbCandidateList_count = wbCandidateListMapper.selectCount(new LambdaQueryWrapper<WbCandidateList>().eq(WbCandidateList::getCandidateId,wbCandidateInfo.getId()));
            if(StringUtils.isNotEmpty(wbCandidateInfo.getPurchaseNo()) && wbCandidateList_count > 0){
                wbCandidateInfo.setStatus("0");
            }else{
                wbCandidateInfo.setStatus("-1");
            }
            listWbCandidateInfo.add(wbCandidateInfo);
        }
    }

    /**
     * 获取html中编号
     * @param content  html内容
     * @param num  定义获取的编号长度
     * @return
     */
    @Override
    public String handleHtmlPurchaseNo(String content,int num) {
        content = content.replace("\\s*|\r|\n|\t","");
        Document doc = Jsoup.parse(content);
        // 获取纯文本内容
        String textOnly = doc.text();
        // 获取"招标编号："的起始位置
        int startIndex = textOnly.indexOf("编号：");
        if(startIndex == -1){
            return null;
        }else{
            startIndex =startIndex+ "编号：".length();
        }
        // 从起始位置开始截取num位字符
        String result = textOnly.substring(startIndex, startIndex + num);
        return result;
    }

    private File convertMultipartFileToFile(MultipartFile file) throws IOException {
        File convFile = null;
        if (file.equals("") || file.getSize() <= 0) {
            System.out.println("File is empty or its size is zero, please check!");
        } else {
            InputStream inputStream = file.getInputStream();
            convFile = new File(file.getOriginalFilename());
            FileOutputStream fos = new FileOutputStream(convFile);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
            fos.close();
            inputStream.close();
        }
        return convFile;
    }

    /**
     * 根据id检查分标分包信息
     * @param id 项目ID
     */
    private void checkBag(Long id){
        Long count = wbDemandListMapper.selectCount(new LambdaQueryWrapper<WbDemandList>().eq(WbDemandList::getItemId,id));
        if(count <= 0){
            List<WbGoodsListInfoVo> list = wbGoodsListInfoMapper.selectListByItemID(id);
            for (WbGoodsListInfoVo wbGoodsListInfoVo:list){
                WbDemandList wbDemandList = new WbDemandList();
                wbDemandList.setSubStandardId(wbGoodsListInfoVo.getSubStandardId());
                wbDemandList.setSubStandardName(wbGoodsListInfoVo.getSubStandardName());
                wbDemandList.setBagId(wbGoodsListInfoVo.getBagId());
                wbDemandList.setBagName(wbGoodsListInfoVo.getBagName());
                wbDemandList.setProvincePurchaseRequisitionNumber(wbGoodsListInfoVo.getProvincePurchaseRequisitionNumber());
                wbDemandList.setItemId(id.toString());
                wbDemandListMapper.insert(wbDemandList);
            }
        }
    }

    /**
     * 保存或修改招标项目
     * @param note 列表数据
     * @param json_notice 详情
     */
    private void insertOrSaveWbItemInfo(JSONObject note,JSONObject json_notice,List<WbItemInfo> list_wbItemInfo,String dataSource,String dataSourceMenu,String docType){
        if(wbItemInfoMapper.selectVoById(note.getLong("id")) == null){
            WbItemInfo wbItemInfo = new WbItemInfo();
            wbItemInfo.setDataSource(dataSource);
            wbItemInfo.setDataSourceMenu(dataSourceMenu);
            wbItemInfo.setId(note.getLong("id"));
            wbItemInfo.setItemId(note.getStr("code"));
            wbItemInfo.setItemName(note.getStr("title"));
            wbItemInfo.setDocType(docType);
            wbItemInfo.setPublishTime(note.getStr("noticePublishTime"));
            wbItemInfo.setOrgId(note.getLong("orgId"));
            wbItemInfo.setTenderee(note.getStr("publishOrgName"));
//        wbItemInfo.setStatus(note.getStr("prjStatus"));
            wbItemInfo.setStatus("-1");
            if("doci-change".equals(note.getStr("doctype"))){//变更公告
                wbItemInfo.setOnlineBidNoticeId(json_notice.getLong("ONLINE_BID_NOTICE_ID"));
            }
            if("doc-spec".equals(note.getStr("doctype"))){//其它公告
                wbItemInfo.setPrjIntroduce(json_notice.getStr("cont"));
            }else{
                wbItemInfo.setPrjIntroduce(json_notice.getStr("PRJ_INTRODUCE"));
            }
            wbItemInfo.setObtainingFileDeadline(json_notice.getStr("BIDBOOK_BUY_END_TIME"));
            wbItemInfo.setBidOpenTime(json_notice.getStr("OPENBID_TIME"));
            wbItemInfo.setType(json_notice.getStr("PUR_TYPE_NAME"));
            wbItemInfo.setLocation(json_notice.getStr("OPENBID_ADDR"));
            wbItemInfo.setPurType(json_notice.getStr("PUR_TYPE"));
            wbItemInfo.setChgNoticeCont(json_notice.getStr("CHG_NOTICE_CONT"));
            wbItemInfo.setContact(json_notice.getStr("CONTACT"));
            wbItemInfo.setContactBy(json_notice.getStr("CONTACTBY"));
            wbItemInfo.setTel(json_notice.getStr("TEL"));
            wbItemInfo.setTelBy(json_notice.getStr("TELBY"));
            wbItemInfo.setEmail(json_notice.getStr("E_MAIL"));
            wbItemInfo.setTax(json_notice.getStr("TAX"));
            wbItemInfo.setBidAgt(json_notice.getStr("BID_AGT"));
            wbItemInfo.setBidAgtAddr(json_notice.getStr("BID_AGT_ADDR"));
            wbItemFileMapper.delete(new LambdaQueryWrapper<WbItemFile>().eq(WbItemFile::getItemId, wbItemInfo.getId()));//下载前清空附件信息
            this.downLoadBid(wbItemInfo.getId().toString());//开始下载文件
            list_wbItemInfo.add(wbItemInfo);
        }
    }

    /**
     * 保存或修改中标结果
     * @param note
     * @param json_notice
     * @param list_WbMinuteBidBag
     */
    private void insertOrSaveWbMinuteBidBag(JSONObject note,JSONObject json_notice,List<WbMinuteBidBag> list_WbMinuteBidBag,String fileFlag){
        if(wbMinuteBidBagMapper.selectVoById(note.getLong("id")) == null){
            WbMinuteBidBag wbMinuteBidBag = new WbMinuteBidBag();
            wbMinuteBidBag.setId(note.getLong("id"));
            wbMinuteBidBag.setDocType(note.getStr("doctype"));
//            wbMinuteBidBag.setItemId(note.getStr("code"));
            wbMinuteBidBag.setItemName(note.getStr("title"));
            wbMinuteBidBag.setBidDate(note.getStr("noticePublishTime"));
            if(StringUtils.isNotEmpty(note.getStr("noticePublishTime"))){
                wbMinuteBidBag.setYear(note.getStr("noticePublishTime").substring(0,4));
            }
            if(StringUtils.isNotEmpty(json_notice.getStr("CONT"))){
                wbMinuteBidBag.setPrjIntroduce(json_notice.getStr("CONT"));
            }else{
                wbMinuteBidBag.setPrjIntroduce(json_notice.getStr("cont"));
            }
            if(StringUtils.isNotEmpty(json_notice.getStr("bidOrgName"))){
                wbMinuteBidBag.setTenderee(json_notice.getStr("bidOrgName"));
            }else{
                wbMinuteBidBag.setTenderee(json_notice.getStr("publishOrgName"));
            }
            if(StringUtils.isNotEmpty(json_notice.getStr("bidagtName"))){
                wbMinuteBidBag.setTenderingAgency(json_notice.getStr("bidagtName"));
            }else{
                wbMinuteBidBag.setTenderingAgency(json_notice.getStr("noticeInscribeOrg"));
            }
            wbMinuteFileMapper.delete(new LambdaQueryWrapper<WbMinuteFile>().eq(WbMinuteFile::getWbMinuteBidBagId, wbMinuteBidBag.getId()));//下载前清空附件信息
            if("1".equals(fileFlag) || "true".equals(fileFlag)){//有文件
                JSONArray jsonArray_file = new JSONArray();
                if("true".equals(fileFlag)){
                    JSONObject json_file = this.getFile(note.getStr("id"));
                    jsonArray_file = json_file.getJSONObject("resultValue").getJSONArray("files");
                }else{
                    JSONObject json_file = this.getWinFile(note.getStr("id"));
                    jsonArray_file = json_file.getJSONObject("resultValue").getJSONArray("files");
                }
                for (int i = 0; i < jsonArray_file.size(); i++) {
                    String item_no = null;
                    JSONObject file = jsonArray_file.getJSONObject(i);
                    if(StringUtils.isNotEmpty(file.getStr("attachName"))){
                        item_no = this.downLoadBidPDF(file.getStr("filePath")+"/"+file.getStr("attachName"),note.getStr("id"),file.getStr("fileName"),"01");//开始下载文件
                    }else{
                        item_no = this.downLoadBidPDF(file.getStr("FILE_PATH"),note.getStr("id"),file.getStr("FILE_NAME"),"01");//开始下载文件
                    }
                    if(item_no != null && item_no.length() > 200) {
                        item_no = item_no.substring(0,200);
                    }
                    item_no = DianWangUtil.handHtmlItemNo(item_no,wbMinuteBidBag.getPrjIntroduce());
                    if(StringUtils.isNotEmpty(item_no) && item_no.length() > 2){
                        wbMinuteBidBag.setItemId(item_no);
                    }
                }
            }else{
                List<Map> list = HtmlToMapConverter.handleHtmlTable(wbMinuteBidBag.getPrjIntroduce());
                List<WbMinuteList> list_obj = analyzeMap(list,"wbMinuteBidBagId",wbMinuteBidBag.getId(),WbMinuteList.class,"WbMinuteList");
                for (int i = 0; i < list_obj.size(); i++) {
                    WbMinuteList wbMinuteList = list_obj.get(i);
                    wbMinuteList.setSort(i+1);
                    if(StringUtils.isNotEmpty(wbMinuteList.getCompanyName())){
                        wbCompanyInfoService.handleName(wbMinuteList.getCompanyName());
                    }
                    if(StringUtils.isNotEmpty(wbMinuteList.getPriceDescription()) && isValidBigDecimal(wbMinuteList.getPriceDescription())){
                        wbMinuteList.setPrice(wbMinuteList.getPriceDescription());
                    }else if(StringUtils.isNotEmpty(wbMinuteList.getSubStandardId()) || StringUtils.isNotEmpty(wbMinuteList.getSubStandardName())){
                        List<WbCandidateListVo> list_cl = wbCandidateListMapper.selectVoList(new LambdaQueryWrapper<WbCandidateList>()
                            .eq(StringUtils.isNotEmpty(wbMinuteList.getSubStandardId()), WbCandidateList::getSubStandardId,wbMinuteList.getSubStandardId())
                            .eq(StringUtils.isNotEmpty(wbMinuteList.getSubStandardName()), WbCandidateList::getSubStandardName,wbMinuteList.getSubStandardName())
                            .eq(StringUtils.isNotEmpty(wbMinuteList.getBagNo()), WbCandidateList::getBagNo,wbMinuteList.getBagNo())
                            .eq(StringUtils.isNotEmpty(wbMinuteList.getBagName()), WbCandidateList::getBagName,wbMinuteList.getBagName()));
                        if(list_cl.size() == 1){
                            wbMinuteList.setPrice(list_cl.get(0).getPriceOrDiscount());
                        }
                    }
                    wbMinuteListMapper.insert(wbMinuteList);
                }
//                wbMinuteListMapper.insertBatch(list_obj);
                //-----------------------获取项目编号----------------------//
                if(StringUtils.isNotEmpty(wbMinuteBidBag.getPrjIntroduce())){
                    String itemNo = DianWangUtil.handHtmlItemNo("",wbMinuteBidBag.getPrjIntroduce());
                    if(StringUtils.isNotEmpty(itemNo) && itemNo.length() > 2){
                        wbMinuteBidBag.setItemId(itemNo);
                    }
                }
            }
            wbMinuteBidBag.setDataSource("ECP");//数据来源：ECP平台
            Long wbMinuteList_count = wbMinuteListMapper.selectCount(new LambdaQueryWrapper<WbMinuteList>().eq(WbMinuteList::getWbMinuteBidBagId,wbMinuteBidBag.getId()));
            if(StringUtils.isNotEmpty(wbMinuteBidBag.getItemId()) && wbMinuteList_count > 0){
                wbMinuteBidBag.setStatus("0");
            }else{
                wbMinuteBidBag.setStatus("-1");
            }
            list_WbMinuteBidBag.add(wbMinuteBidBag);
        }
    }


}
